import Graph from "./getBusinessTopoData.js";


const {
  graph,
  height,
  width,
  nodes,
  edges,
  nodeMap,
  gColors,
  edgesMap,
  showNodes,
  showEdges,
} = Graph;
 
let curShowNodes = showNodes;
let curShowEdges = $.extend(true, [], showEdges);
let highlighting = false;
let hideMap = new Map();

function refreshDragedNodePosition(e) {
  const model = e.item.get("model");
  model.fx = e.x;
  model.fy = e.y;
}

graph.get("canvas").set("localRefresh", false);

graph.on("node:dragstart", (e) => {
  graph.layout();
  refreshDragedNodePosition(e);
});
graph.on("node:drag", (e) => {
  refreshDragedNodePosition(e);
});
graph.on("node:dragend", (e) => {
  e.item.get("model").fx = null;
  e.item.get("model").fy = null;
});
graph.on("node:mouseenter", (e) => {
  const item = e.item;
  const model = item.getModel();
  const model1 = item.getEdges();

  highlighting = true;
  graph.setAutoPaint(false);

  const nodeItems = graph.getNodes();
  const edgeItems = graph.getEdges();

  // 重置 node 状态
  nodeItems.forEach((node) => {
    graph.setItemState(node, "dark", true);
    node.getModel().light = false;
  });
  graph.setItemState(item, "dark", false);
  model.light = true;
  // console.log("model", model, model1);

  // 重置 edge 状态
  edgeItems.forEach((item, idx) => {
    const source = item.getSource().getModel();
    const target = item.getTarget().getModel();
    if (source.light && target.light) {
      graph.setItemState(item, "dark", false);
    } else {
      graph.setItemState(item, "light", true);
    }
  });
  // 明天改成影响的下游
  model1.forEach((item, idx) => {
    const source = item.getSource().getModel();
    const target = item.getTarget().getModel();
    if (source.light && target.light) {
      graph.setItemState(item, "dark", false);
    } else {
      graph.setItemState(item, "dark", true);
    }
  });
  graph.paint();
  graph.setAutoPaint(true);
});

// graph.on("node:mouseenter", function (e) {
//   var item = e.item;
//   graph.setAutoPaint(false);
//   graph.getNodes().forEach(function (node) {
//     graph.clearItemStates(node);
//     graph.setItemState(node, "dark", true);
//   });
//   graph.setItemState(item, "dark", false);
//   graph.setItemState(item, "highlight", true);
//   graph.getEdges().forEach(function (edge) {
//     if (edge.getSource() === item) {
//       graph.setItemState(edge.getTarget(), "dark", false);
//       graph.setItemState(edge.getTarget(), "highlight", true);
//       graph.setItemState(edge, "highlight", true);
//       edge.toFront();
//     } else if (edge.getTarget() === item) {
//       graph.setItemState(edge.getSource(), "dark", false);
//       graph.setItemState(edge.getSource(), "highlight", true);
//       graph.setItemState(edge, "highlight", true);
//       edge.toFront();
//     } else {
//       graph.setItemState(edge, "highlight", false);
//     }
//   });
//   graph.paint();
//   graph.setAutoPaint(true);
// });

graph.on("node:mouseleave", () => {
  if (highlighting) {
    const nodeItems = graph.getNodes();
    const edgeItems = graph.getEdges();
    highlighting = false;
    // console.log("nodeItems", nodeItems);
    nodeItems.forEach((item) => {
      graph.setItemState(item, "dark", false);
    });
    edgeItems.forEach((item) => {
      graph.setItemState(item, "dark", false);
    });
  }
});

// 点击节点折叠或展开
graph.on("node:click", (e) => {
  const item = e.item;
  //点击的节点实例
  const model = item.getModel();

  // console.log("curShowNodes", curShowNodes);
  console.log("model", model, model.id, model.collapse);
  //节点展开逻辑
  // 如果单击一个根，隐藏不相关的项，并显示相关的项
  const layoutController = graph.get("layoutController");
  const forceLayout = layoutController.layoutMethods[0];
  forceLayout.forceSimulation.stop();
  //点击的根节点居中归位
  // model.x = width / 2;
  // model.y = height / 2;
  console.log("curShowNodes", curShowNodes, showNodes);
  // 单击同一节点即当前的焦点节点，隐藏小节点，将布局参数更改为根视图
  if (model.collapse) {
    model.collapse = false;
    layoutController.layoutCfg.nodeStrength = -100;
    layoutController.layoutCfg.collideStrength = 0.8;
    layoutController.layoutCfg.alphaDecay = 0.01;

    const hideNodes = hideMap.get(model.id).hideNodes;
    const hideEdges = hideMap.get(model.id).hideEdges;

    curShowNodes = curShowNodes.concat(hideNodes);
    curShowEdges = curShowEdges.concat(hideEdges);
    console.log("uncollapse", curShowNodes, curShowEdges);
  } else {
    // 单击其他焦点节点，隐藏当前小节点，显示相关节点
    model.collapse = true;
    //节点作用力，正数代表节点之间的引力作用，负数代表节点之间的斥力作用
    layoutController.layoutCfg.nodeStrength = () => {
      return -100;
    };
    layoutController.layoutCfg.collideStrength = 0.8; //防止重叠力度

    // 找到被点击节点的后代节点
    let hideArr = findDownstreamNodes(model.id);
    console.log("hideArr", hideArr, hideMap);
    // 隐藏不相关的节点和边
    const hideNodes = curShowNodes.filter((node) => hideArr.includes(node.id));
    const hideEdges = curShowEdges.filter((edge) =>
      hideArr.includes(edge.target)
    );
    hideMap.set(model.id, { hideNodes, hideEdges });

    curShowNodes = curShowNodes.filter((node) => !hideArr.includes(node.id));
    curShowEdges = curShowEdges.filter(
      (edge) => !hideArr.includes(edge.target)
    );
    console.log("collapse", model.collapse, curShowNodes, curShowEdges);

    setDisappearingState(hideEdges, hideNodes);
  }

  setTimeout(() => {
    graph.changeData({
      nodes: curShowNodes,
      edges: curShowEdges,
    });
    const nodeItems = graph.getNodes();
    const edgeItems = graph.getEdges();
    edgeItems.forEach((item) => {
      graph.clearItemStates(item);
    });
    nodeItems.forEach((item) => {
      graph.clearItemStates(item);
      graph.setItemState(item, "appearing", true);
    });
  }, 100);
});
graph.on("canvas:click", () => {
  const forceLayout = graph.get("layoutController").layoutMethods[0];
  forceLayout.forceSimulation.stop();
  const nodeItems = graph.getNodes();
  const edgeItems = graph.getEdges();
  if (highlighting) {
    highlighting = false;
    nodeItems.forEach((item) => {
      graph.setItemState(item, "dark", false);
    });
    edgeItems.forEach((item) => {
      graph.setItemState(item, "dark", false);
    });
  } else {
    nodeItems.forEach((item) => {
      graph.setItemState(item, "disappearing", true);
    });
    edgeItems.forEach((item) => {
      graph.setItemState(item, "disappearing", true);
    });

    setTimeout(() => {
      const layoutController = graph.get("layoutController");
      layoutController.layoutCfg.nodeStrength = -100;
      layoutController.layoutCfg.collideStrength = 0.8;
      layoutController.layoutCfg.alphaDecay = 0.01;

      // 视图重置了，需要重新设置状态
      console.log("reset view");
      curShowNodes = showNodes.map((node) => {
        node.collapse = false;
        return node;
      });
      curShowEdges = showEdges;

      graph.changeData({
        nodes: curShowNodes,
        edges: curShowEdges,
      });
    }, 100);
  }
});

//查找节点关联和级联节点
function findDownstreamNodes(startNodeId) {
  // 创建一个Set用于存储已经访问过的节点ID，避免重复访问
  const visited = new Set();
  // 创建一个队列用于BFS遍历，初始化为包含起始节点
  const queue = [startNodeId];
  // 将起始节点标记为已访问
  visited.add(startNodeId);

  while (queue.length > 0) {
    // 从队列中取出第一个元素
    const currentId = queue.shift();
    // 遍历所有边，寻找与当前节点相关联的“target”节点（即下游节点）
    edges.forEach((edge) => {
      if (edge.source === currentId && !visited.has(edge.target)) {
        // 如果找到新的未访问下游节点，则加入到队列和已访问集合中
        visited.add(edge.target);
        queue.push(edge.target);
      }
    });
  }

  // 返回除起始节点外的所有下游关联和级联节点ID
  return Array.from(visited).filter((id) => id !== startNodeId);
}

// 生动地隐藏将要消失的节点和边
function setDisappearingState(edges, nodes) {
  if (edges.length) {
    edges.forEach((csedge) => {
      const item = graph.findById(csedge.id);
      //应用隐藏动画
      item && graph.setItemState(item, "disappearing", true);
    });
  }

  nodes.forEach((csnode) => {
    const item = graph.findById(csnode.id);
    item && graph.setItemState(item, "disappearing", true);
  });
  graph.positionsAnimate();
}
